import { Injectable, InternalServerErrorException } from '@nestjs/common';
import * as qiniu from 'qiniu';
import { ConfigService } from '@nestjs/config';
import axios from 'axios';
import { createHmac } from 'crypto';

@Injectable()
export class QiniuService {
  private mac: qiniu.auth.digest.Mac;
  private config: qiniu.conf.Config;

  constructor(private configService: ConfigService) {
    this.mac = new qiniu.auth.digest.Mac(
      configService.get('QINIU_ACCESS_KEY'),
      configService.get('QINIU_SECRET_KEY'),
    );
    this.config = new qiniu.conf.Config();
  }

  // 生成审核鉴权token
  generateQiniuAuthToken(
    url: string,
    method: string,
    contentType: string = 'application/json',
    bodyString: string,
  ) {
    const parsedUrl = new URL(url);
    const path = parsedUrl.pathname;
    const host = parsedUrl.host;

    // 构造待签名的原始字符串
    const dataToSign = [
      `${method.toUpperCase()} ${path}\n`,
      `Host: ${host}\n`,
      `Content-Type: ${contentType}\n`,
      '\n',
      `${bodyString}`,
    ].join('');

    // 计算 HMAC-SHA1 签名
    const sign = createHmac('sha1', this.configService.get('QINIU_SECRET_KEY'))
      .update(dataToSign)
      .digest('base64');
    // 拼接 Authorization Token
    return `Qiniu ${this.configService.get('QINIU_ACCESS_KEY')}:${sign}`;
  }

  // 发起视频内容审核
  async censorVideo(key: string, videoId: number, callbackUrl?: string) {
    /* 请求参数配置 */
    const ossVideoUrl = `${this.configService.get('QINIU_DOMAIN')}/${key}`;
    // 构造请求体
    const requestBody = {
      data: {
        uri: ossVideoUrl,
        id: `video_${key}`, // 使用文件key作为任务ID
        // callback: callbackUrl,
      },
      params: {
        scenes: ['pulp', 'terror', 'politician'],
        cut_param: {
          interval_msecs: 5000,
        },
      },
    };
    // 请求配置
    const method = 'POST';
    const url = 'https://ai.qiniuapi.com/v3/video/censor';
    const contentType = 'application/json';
    const bodyString = JSON.stringify(requestBody);

    // 生成鉴权Token
    const accessToken = this.generateQiniuAuthToken(
      url,
      method,
      contentType,
      bodyString,
    );

    // 构造请求头
    const headers = {
      'Content-Type': contentType,
      Authorization: `${accessToken}`,
    };

    /* 发送审核请求 */
    const response = await axios.post(url, bodyString, { headers });

    // 第三方视频审核API接口返回response.data.job 为审核任务ID
    // 通过审核任务ID可以查询审核结果

    /* 返回审核结果 */
    return response.data.job;
  }

  // 同步审核文本
  async censorText(content: string) {
    /* 请求参数配置 */
    // 构造请求体
    const requestBody = {
      data: {
        text: content,
      },
      params: {
        scenes: ['antispam'],
      },
    };

    // 请求配置
    const method = 'POST';
    const url = 'https://ai.qiniuapi.com/v3/text/censor';
    const contentType = 'application/json';
    const bodyString = JSON.stringify(requestBody);

    // 生成鉴权Token
    const accessToken = this.generateQiniuAuthToken(
      url,
      method,
      contentType,
      bodyString,
    );

    // 构造请求头
    const headers = {
      'Content-Type': contentType,
      Authorization: `${accessToken}`,
    };

    /* 发送审核请求 */
    try {
      //   直接通过-未购买审核服务
      //   const response: any = await axios.post(url, bodyString, { headers });
      //   if (response.data.code === 200) {
      //     return 'pass';
      //   } else {
      //     return 'reject';
      //   }
      return 'pass';
    } catch (error) {
      // 抛出500错误服务器内部出错
      throw new Error('服务器内部出错');
    }
  }

  /**
   * @description 获取视频审核结果
   */
  async getVideoCensorResult(jobId: number) {
    /* 请求参数配置 */

    // 请求配置
    const method = 'GET';
    const url = 'https://ai.qiniuapi.com/v3/jobs/video';

    const parsedUrl = new URL(url);
    const path = parsedUrl.pathname;
    const host = parsedUrl.host;

    // 构造待签名的原始字符串
    const dataToSign = [
      `${method.toUpperCase()} ${path}\n`,
      `Host: ${host}\n`,
    ].join('');

    // 计算 HMAC-SHA1 签名
    const sign = createHmac('sha1', this.configService.get('QINIU_SECRET_KEY'))
      .update(dataToSign)
      .digest('base64');

    const accessToken = `Qiniu ${this.configService.get('QINIU_ACCESS_KEY')}:${sign}`;

    // 构造请求头
    const headers = {
      Authorization: `${accessToken}`,
    };

    try {
      /* 发送审核请求 */
      const response = await axios.get(url + `/${jobId}`, { headers });
    } catch (error) {
      // 抛出500错误服务器内部出错
      throw new Error('服务器内部出错');
    }

    /* 返回审核结果 */
    return 'success';
  }

  /**
   * 获取七牛云视频元信息
   * @param key 七牛云视频文件名/key
   * @returns 视频元信息
   */
  async getVideoInfo(key: string) {
    try {
      // 确保使用完整的URL
      const fullUrl = this.getFullUrl(key);

      // 初始化七牛云SDK
      const accessKey = this.configService.get('QINIU_ACCESS_KEY');
      const secretKey = this.configService.get('QINIU_SECRET_KEY');
      const bucket = this.configService.get('QINIU_BUCKET');

      // 创建七牛授权对象
      const mac = new qiniu.auth.digest.Mac(accessKey, secretKey);
      const config = new qiniu.conf.Config();

      // 构建avinfo API URL
      const encodedKey = encodeURIComponent(key);
      const avInfoUrl = `http://api.qiniu.com/avinfo?key=${encodedKey}`;

      return new Promise((resolve, reject) => {
        // 使用BucketManager获取视频信息
        const bucketManager = new qiniu.rs.BucketManager(mac, config);
        bucketManager.fetch(
          avInfoUrl,
          bucket,
          null,
          (err, respBody, respInfo) => {
            if (err) {
              console.error('获取视频信息失败:', err);
              reject(new InternalServerErrorException('获取视频信息失败'));
            }

            if (respInfo.statusCode !== 200) {
              console.error('获取视频信息失败:', respInfo.statusCode, respBody);
              reject(new InternalServerErrorException('获取视频信息失败'));
            }

            // 处理并返回视频信息
            resolve({
              code: 200,
              message: '获取视频信息成功',
              data: respBody,
            });
          },
        );
      });
    } catch (error) {
      console.error('获取视频信息失败:', error);
      throw new InternalServerErrorException('获取视频信息失败');
    }
  }

  /**
   * 获取完整的资源URL
   * @param key 七牛云文件名/key
   * @returns 完整的资源URL
   */
  private getFullUrl(key: string): string {
    // 如果已经是完整URL，直接返回
    if (key.startsWith('http://') || key.startsWith('https://')) {
      return key;
    }

    // 否则，拼接域名和key
    const domain = this.configService.get('QINIU_DOMAIN');
    return `${domain}/${key}`;
  }
}
